#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# combo_presence.py 
#
#  Copyright (c) 2006-2007 INdT (Instituto Nokia de Technologia)
#                2007 Kenneth Rohde Christiansen
#
#  Author: Kenneth Rohde Christiansen <kenneth.christiansen@gmail.com>
#          Renato Araujo Oliveira Filho <renato.filho@indt.org.br>
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
#  USA

import pygtk
pygtk.require("2.0")
import gtk
import gobject
import pango
import os
import tapioca

from local_contact_store import LocalContactStore
from dialogs import SignOutDialog

class ComboPresence(gtk.ComboBox):

    __gsignals__ = {
        'change-presence' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,)),
        'custom-presence' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, 
                (gobject.TYPE_PYOBJECT,)),
        'sign-out' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT,)),
    }

    (
    COMBO_PRESENCE_IMAGE,
    COMBO_PRESENCE_TEXT,
    COMBO_PRESENCE_VALUE,
    COMBO_PRESENCE_FIXED
    ) = range(4)

    CLEAR_CUSTOM_MESSAGE = -1

    def __init__(self, main_app, local_contact_store, my_id):
        gtk.ComboBox.__init__(self)
        self.clear()

        self.main_app = main_app

        self.local_contact_store = local_contact_store
        self.my_id = my_id

        self.last_presence_selection = None
        self.last_active_item = 0

        self.ereseva_dir = os.path.expanduser(os.environ.get('HOME')) + '/.ereseva'

        self.set_row_separator_func(self.separator_func)

        cell_pix = gtk.CellRendererPixbuf()
        cell_pix.set_fixed_size(22, -1)

        self.pack_start(cell_pix, False)
        self.add_attribute(cell_pix, "pixbuf", 0)

        cell_text = gtk.CellRendererText()
        cell_text.set_property('ellipsize', pango.ELLIPSIZE_END)
        self.pack_start(cell_text, True)
        self.add_attribute(cell_text, "markup", 1)
        #cell_text.set_ellipsize(pango.ELLIPSIZE_END)

        self.custom_store = gtk.ListStore (gtk.gdk.Pixbuf,     # Presence image
                           str,         # Presence text
                           int,         # ContactPresence
                           bool         # Fixed presence
                          )

        self.set_model(self.custom_store)

        # Available section
        pixbuf = self.local_contact_store.get_presence_icon_from_presence(\
                tapioca.PRESENCE_AVAILABLE)
        self.custom_store.append([pixbuf, "Available", \
                tapioca.PRESENCE_AVAILABLE, True])
        self.custom_store.append([pixbuf, "Custom message...", \
                tapioca.PRESENCE_AVAILABLE, True])
        self.custom_store.append([None, "--", 0, True])

        # Busy section
        pixbuf = self.local_contact_store.get_presence_icon_from_presence(\
            tapioca.PRESENCE_BUSY)
        self.custom_store.append([pixbuf, "Busy", \
                tapioca.PRESENCE_BUSY, True])
        self.custom_store.append([pixbuf, "Custom message...", \
                tapioca.PRESENCE_BUSY, True])
        self.custom_store.append([None, "--", 0, True])

        # Away section
        pixbuf = self.local_contact_store.get_presence_icon_from_presence(\
                tapioca.PRESENCE_AWAY)
        self.custom_store.append([pixbuf, "Away", \
                tapioca.PRESENCE_AWAY, True])
        self.custom_store.append([pixbuf, "Custom message...", \
                tapioca.PRESENCE_AWAY, True])
        self.custom_store.append([None, "--", 0, True])

        # The other section
        pixbuf = self.local_contact_store.get_presence_icon_from_presence(\
                tapioca.PRESENCE_OFFLINE)
        self.custom_store.append([pixbuf, "Sign out of chat", \
                tapioca.PRESENCE_OFFLINE, True])
        self.custom_store.append([None, "Clear custom messages", \
                self.CLEAR_CUSTOM_MESSAGE, True])

        self.connect("changed", self.on_changed)


    def set_id(self, my_id):
        self.my_id = my_id


    def insert_value (self, pixbuf, text, presence):
        row_iter = self.custom_store.prepend()
        self.custom_store.set_value(row_iter, 0, pixbuf)
        self.custom_store.set_value(row_iter, 1, gobject.escape_markup_text(text))
        self.custom_store.set_value(row_iter, 2, int(presence))
        self.custom_store.set_value(row_iter, 3, True)


    def get_presence(self, row_iter=None):
        if row_iter == None:
            row_iter = self.get_active_iter()

        return int(self.custom_store.get_value(row_iter, self.COMBO_PRESENCE_VALUE))


    def get_presence_iter(self, presence):
        row_iter = self.custom_store.get_iter_first()

        while row_iter:
            if self.get_presence(row_iter) == presence:
                return row_iter

            row_iter = self.custom_store.iter_next(row_iter)

        return None


    def get_description(self, row_iter=None):
        if row_iter == None:
            row_iter = self.get_active_iter()

        return self.custom_store.get(row_iter, self.COMBO_PRESENCE_TEXT)[0]


    def set_presence(self, presence, text=None):
        if text == None:
            self.set_active_iter(self.get_presence_iter(presence))
        else:
            #later
            pass


    def update_custom_presence (self, presence, description):
        if presence == -1:
            return

        self.insert_custom_presence(presence, description)

        active_iter = self.get_active_iter()

        if active_iter.equals(self.custom_iter):
            print "Custom presence %s" % presence


    def on_changed(self, widget):
        path = widget.get_active()
        active_iter =  self.custom_store.get_iter(path)

        presence = self.get_presence()
        presence_text = self.get_description()

        if presence == self.CLEAR_CUSTOM_MESSAGE:
            self.clear_custom_presences()

            if self.last_presence_selection != None:
                self.set_active_iter( \
                        self.get_presence_iter(self.last_presence_selection))

            self.last_presence_selection = presence

        elif presence == tapioca.PRESENCE_OFFLINE:

            if len(self.main_app.chat_windows) > 0:
                dialog = SignOutDialog()
                response = dialog.run()
                dialog.destroy()

                if response == gtk.RESPONSE_YES:
                    self.emit('sign-out', None)
                else:
                    self.set_active(self.last_active_item)
            else:
                self.emit('sign-out', None)

        elif presence == tapioca.PRESENCE_AVAILABLE or \
                presence == tapioca.PRESENCE_BUSY or \
                presence == tapioca.PRESENCE_AWAY:

            if presence_text == 'Custom message...':
                self.emit('custom-presence', presence)
            else:
                is_custom_presence = not bool(self.custom_store.get_value(active_iter, \
                                                self.COMBO_PRESENCE_FIXED))

                if is_custom_presence:
                    custom_message = presence_text
                else:
                    custom_message = None

                self.last_active_item = path
                self.emit('change-presence', presence, custom_message)

            self.last_presence_selection = presence

        else:
            print 'others'


    def insert_custom_presence(self, presence, text):
        presence_iter = self.get_presence_iter(presence)
        pixbuf = \
                self.local_contact_store.get_presence_icon_from_presence(presence)
        new_iter = self.custom_store.insert_after(presence_iter, \
                [pixbuf, text, presence, False])

        return new_iter

    def clear_custom_presences(self):
        """
        Function that clears all custom presences.
        """

        row_iter = self.custom_store.get_iter_first()

        to_remove = []

        while row_iter:
            is_fixed_presence = bool(self.custom_store.get_value(row_iter, \
                    self.COMBO_PRESENCE_FIXED))

            if not is_fixed_presence:
                to_remove.append(row_iter)

            row_iter = self.custom_store.iter_next(row_iter)

        for row_iter in to_remove:
            self.custom_store.remove(row_iter)


    def separator_func(self, model, row_iter):
        """
        A separator callback function for the combobox model
        """

        if model.get_value(row_iter, 1) == "--":
            return True
        else:
            return False


    def load_custom_presences(self):
        """
        Loads the user custom presence messages.
        """

        presence_filename = self.ereseva_dir + '/' + self.my_id + '.presence.txt'

        if not os.path.exists(presence_filename):
            self.set_presence(tapioca.PRESENCE_AVAILABLE)
            return

        presence_file = open(presence_filename, 'r')
        presence_file_lines = presence_file.readlines()
        presence_file.close()

        entry = 0 # Available

        for line in presence_file_lines:
            i = line.index(' ')
            first_part = line[:i].strip()
            second_part = line[i+1:].strip()

            if first_part == "entry":
                entry = int(second_part)
                msg = None
            else:
                presence = int(first_part)
                i = second_part.index('"') + 1
                e = second_part.rindex('"')
                msg = second_part[i:e]

            if msg != None and presence in (tapioca.PRESENCE_AVAILABLE, \
                                            tapioca.PRESENCE_BUSY, \
                                            tapioca.PRESENCE_AWAY):
                self.insert_custom_presence(presence, msg)

        self.set_active(entry)


    def save_custom_presences(self):
        """
        Saves the user custom presence messages.
        """

        row_iter = self.custom_store.get_iter_first()

        print self.last_active_item
        lines_to_save = ["entry %d\n" % self.last_active_item]

        while row_iter:
            is_custom_presence = not bool(self.custom_store.get_value(row_iter, \
                    self.COMBO_PRESENCE_FIXED))

            if is_custom_presence:
                presence = self.get_presence(row_iter)
                presence_message = self.get_description(row_iter)
                text = '%d "%s"\n' % (presence, presence_message)
                lines_to_save.append(text)

            row_iter = self.custom_store.iter_next(row_iter)

        presence_filename = self.ereseva_dir + '/' + self.my_id + '.presence.txt'

        presence_file = open(presence_filename, 'w')
        presence_file.writelines(lines_to_save)
        presence_file.close()


if __name__ == "__main__":
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    combo = ComboPresence(LocalContactStore(), 'setanta@gmail.com')

    window.add(combo)
    window.show_all()
    window.connect('delete-event', gtk.main_quit)

    gtk.main()
